const { numberUtil } = require('../../util')
const Proxy = require('../../proxy')

const ExecuteRecord = Proxy.ExecuteRecord

module.exports = {
  // 获取被兑现的数量
  getTradePingPositionAmt () {
    let positionAmt = Math.abs(this.beforeSymbolAccount.positionAmt)
    if (this.requestBuySellType === 'sell') {
      if (this.beforeSymbolAccount.hasPosition && this.beforeSymbolAccount.hasDuoPosition) {
        return positionAmt
      }
    } else if (this.requestBuySellType === 'buy') {
      if (this.beforeSymbolAccount.hasPosition && this.beforeSymbolAccount.hasKongPosition) {
        return positionAmt
      }
    } else if (this.requestBuySellType === 'pingDuo') {
      if (this.beforeSymbolAccount.hasPosition && this.beforeSymbolAccount.hasDuoPosition) {
        return this.btbModelUpdateParams.buySellQuantity
      }
    } else if (this.requestBuySellType === 'pingKong') {
      if (this.beforeSymbolAccount.hasPosition && this.beforeSymbolAccount.hasKongPosition) {
        return this.btbModelUpdateParams.buySellQuantity
      }
    }
    return 0
  },
  getTradeIncome () {
    let rawIncome = this.beforeSymbolAccount.unrealizedProfit || 0
    let pingPositionAmt = this.getTradePingPositionAmt()
    if (rawIncome && pingPositionAmt && this.beforeSymbolAccount.positionAmt) {
      return (pingPositionAmt / Math.abs(this.beforeSymbolAccount.positionAmt)) * rawIncome
    }
    return 0
  },
  getTradeCommissionOneWay () {
    const usdt = this.btbModelUpdateParams.buySellQuantity * this.btbItem.close
    return numberUtil.keepEightDecimals(usdt * 0.0005)
  },
  // 合并的手续费
  getTradeCommission () {
    const notional = Math.abs(this.beforeSymbolAccount.notional || 0)
    let pingPositionAmt = this.getTradePingPositionAmt()
    if (notional && pingPositionAmt && this.beforeSymbolAccount.positionAmt) {
      // 手续费，开仓和平仓各万5，这里方便起见合并为千1
      return numberUtil.keepEightDecimals((pingPositionAmt / Math.abs(this.beforeSymbolAccount.positionAmt)) * notional * 0.001)
    }
    return 0
  },
  getTradeCommissionMargin () {
    const initialMargin = Math.abs(this.beforeSymbolAccount.initialMargin || 0)
    let pingPositionAmt = this.getTradePingPositionAmt()
    if (initialMargin && pingPositionAmt && this.beforeSymbolAccount.positionAmt) {
      // 手续费，开仓和平仓各万5，这里方便起见合并为千1
      return numberUtil.keepFourDecimals((pingPositionAmt / Math.abs(this.beforeSymbolAccount.positionAmt)) * initialMargin)
    }
    return 0
  },
  // 获取上一笔交易
  async getLastTradingRecord (code, type) {
    const oldList = await ExecuteRecord.find({
      market: 2,
      code: code,
      type
    }, {
      skip: 0,
      limit: 1,
      sort: '-create_at'
    }) || []
    return oldList[0] || {}
  },
  getLastTradeType (val) {
    if (val === 'buy' || val === 'pingKong') {
      return 'sell'
    }
    if (val === 'sell' || val === 'pingDuo') {
      return 'buy'
    }
  },
  // 创建交易记录
  async requestCreateTradeRecord () {
    if (!this.requestOrderId) {
      return
    }
    const lastRecord = await this.getLastTradingRecord(this.btbItem.code, this.getLastTradeType(this.requestBuySellType))
    const tradeIncome = this.getTradeIncome()
    const pingPositionAmt = this.getTradePingPositionAmt()
    const params = {
      code: this.btbItem.code,
      market: 2,
      type: this.requestBuySellType,
      // 原因,英文key
      reason: this.tradeReason,
      orderId: this.requestOrderId,
      // 杠杆
      leverage: this.btbLeverage,
      // 数量
      quantity: this.btbModelUpdateParams.buySellQuantity,
      usdt: Math.abs(numberUtil.keepFourDecimals(this.btbModelUpdateParams.buySellQuantity * this.btbItem.close)),
      price: this.btbItem.close,
      before_quantity: this.beforeSymbolAccount.positionAmt || 0,
      // 手续费千1
      income: tradeIncome,
      ping_quantity: numberUtil.keepEightDecimals(pingPositionAmt),
      commission: this.getTradeCommission(),
      commission_one_way: this.getTradeCommissionOneWay(),
      commission_margin: this.getTradeCommissionMargin(),
      income_res_quantity: this.beforeSymbolAccount.positionAmt || 0,
      income_rate: (this.beforeSymbolAccount.incomeMarginRate || 0),
      track_list: this.trackList,
      strategy: this.strategy,
      strategy_result: this.strategyResult,
      last_strategy: lastRecord.strategy || '',
      last_strategy_result: lastRecord.strategy_result || '',
      // lastType: String,
      // lastReason: String,
      lastId: lastRecord._id,
      keep_days: this.btbItem.keep_days,
      add_times: this.btbModelUpdateParams.add_times,
      price_change_percent: this.btbItem.price_change_percent,
      quote_volume: this.btbItem.quote_volume,
      no_cover_reason: !this.ifCoverBtbBuySellReason() ? 1 : 0,
      // 详情
      detail: {
        positionConfig: this.futuresAccount.positionConfig,
        dictionaryPosition: this.futuresAccount.dictionaryPosition,
        quoteVolumeSum: (this.marketInfo && this.marketInfo.quoteVolumeSum) || 0,
        marketBtbListLen: (this.marketInfo && this.marketInfo.marketBtbListLen) || 0,
        marketPriceChangePercent: (this.marketInfo && this.marketInfo.marketPriceChangePercent) || 0,
        max50AvRate: (this.marketInfo && this.marketInfo.max50AvRate) || 0,
        min50AvRate: (this.marketInfo && this.marketInfo.min50AvRate) || 0,
        onlyDuo: (this.marketInfo && this.marketInfo.onlyDuo) || false,
        onlyKong: (this.marketInfo && this.marketInfo.onlyKong) || false,
        likeDuo: (this.marketInfo && this.marketInfo.likeDuo) || false,
        likeKong: (this.marketInfo && this.marketInfo.likeKong) || false,
        crash15m: (this.marketInfo && this.marketInfo.crash15m) || false,
        attack15m: (this.marketInfo && this.marketInfo.attack15m) || false,
        attack15mKdjDown: (this.marketInfo && this.marketInfo.attack15mKdjDown) || false,
        attack15mKdjGood: (this.marketInfo && this.marketInfo.attack15mKdjGood) || false,
        crash15mKdjUp: (this.marketInfo && this.marketInfo.crash15mKdjUp) || false,
        crash15mKdjGood: (this.marketInfo && this.marketInfo.crash15mKdjGood) || false,
        likeDuoKdjDown: (this.marketInfo && this.marketInfo.likeDuoKdjDown) || false,
        likeDuoKdjGood: (this.marketInfo && this.marketInfo.likeDuoKdjGood) || false,
        likeKongKdjUp: (this.marketInfo && this.marketInfo.likeKongKdjUp) || false,
        likeKongKdjGood: (this.marketInfo && this.marketInfo.likeKongKdjGood) || false,
        kdj4hBad: (this.marketInfo && this.marketInfo.kdj4hBad) || false,
        kdj4hGood: (this.marketInfo && this.marketInfo.kdj4hGood) || false,
        asCount: (this.marketInfo && this.marketInfo.asCount) || 0,
        disabledBuySell: (this.marketInfo && this.marketInfo.disabledBuySell) || false,
        countSumModelInfo: (this.marketInfo && this.marketInfo.countSumModelInfo) || {},
        countModel1d: (this.marketInfo && this.marketInfo.countModel1d) || {},
        countModel1h: (this.marketInfo && this.marketInfo.countModel1h) || {},
        countModel4h: (this.marketInfo && this.marketInfo.countModel4h) || {},
        countModel15m: (this.marketInfo && this.marketInfo.countModel15m) || {},
        info15m: this.analysisInfoFlag15m.getTradeMainInfo ? this.analysisInfoFlag15m.getTradeMainInfo() : {},
        info1h: this.analysisInfoFlag1h.getTradeMainInfo ? this.analysisInfoFlag1h.getTradeMainInfo() : {},
        info4h: this.analysisInfoFlag4h.getTradeMainInfo ? this.analysisInfoFlag4h.getTradeMainInfo() : {},
        info1d: this.analysisInfoFlag1d.getTradeMainInfo ? this.analysisInfoFlag1d.getTradeMainInfo() : {},
        ...this.indexFlagInfo,
        ...this.marketFlagInfo,
        buySellRawTotalWalletBalance: this.buySellRawTotalWalletBalance,
        useMaxIndexBuySellPosition: this.useMaxIndexBuySellPosition
      }
    }
    let realRate = numberUtil.keepTwoDecimals(params.income_rate - (0.1 * params.leverage))
    if (params.commission && params.commission_margin) {
      realRate = numberUtil.countRate(params.income, params.commission_margin)
    }
    params.loss_many = realRate < -32 ? 1 : 0
    if (lastRecord._id) {
      const updateData = {
        income_result: lastRecord.income_result || 0,
        commission_margin_result: lastRecord.commission_margin_result || 0,
        income_rate_result: lastRecord.income_rate_result || 0
      }
      const income_result = numberUtil.keepTwoDecimals((params.income || 0) - (params.commission || 0))
      updateData.income_result = numberUtil.keepTwoDecimals(updateData.income_result + income_result)
      updateData.commission_margin_result = numberUtil.keepTwoDecimals(updateData.commission_margin_result + params.commission_margin)
      updateData.income_rate_result = numberUtil.countRate(updateData.income_result, updateData.commission_margin_result)
      // 记录总的保证金
      await ExecuteRecord.update({
        _id: lastRecord._id
      }, updateData)
    }
    await ExecuteRecord.newAndSave(params)
  },
  findStopExecuteOrder () {
    if (
      Math.abs(this.btbItem.now_position_usdt) > 3 &&
      Math.abs(this.symbolAccount.notional) < 2
    ) {
      // 有发生情况
      return 'profit'
    }
    return false
  },
  // 创建爆仓和止盈交易记录
  async requestCreateStopTradeRecord () {
    // 是在当前K被平掉的
    const requestBuySellType = this.btbItem.now_position_amt > 0 ? 'pingDuo' : 'pingKong'
    const lastRecord = await this.getLastTradingRecord(this.btbItem.code, this.getLastTradeType(requestBuySellType))
    const pingPositionAmt = Math.abs(this.btbItem.now_position_amt) || 0
    let pingPrice = this.btbItem.stop_profit_price
    let type = 'stopProfit'
    // 爆仓的情况
    if (this.btbItem.now_position_amt > 0) {
      // 多单
      if (this.btbItem.close < this.btbItem.now_position_cost_price) {
        type = 'marginCall'
        pingPrice = this.btbItem.now_position_cost_price * (1 - (1 / this.btbItem.leverage))
      }
    } else {
      // 空单
      if (this.btbItem.close > this.btbItem.now_position_cost_price) {
        type = 'marginCall'
        pingPrice = this.btbItem.now_position_cost_price * (1 + (1 / this.btbItem.leverage))
      }
    }
    const usdt = (pingPositionAmt * pingPrice) || 0
    let tradeIncome = ((pingPrice - this.btbItem.now_position_cost_price) * (this.btbItem.now_position_amt || 0)) || 0
    const params = {
      code: this.btbItem.code,
      market: 2,
      type: requestBuySellType,
      // 原因,英文key
      reason: type,
      orderId: '',
      // 杠杆
      leverage: this.btbItem.leverage,
      // 数量
      quantity: pingPositionAmt,
      usdt: Math.abs(numberUtil.keepFourDecimals(usdt)) || 0,
      price: pingPrice || 0,
      before_quantity: this.btbItem.now_position_amt || 0,
      // 手续费千1
      income: tradeIncome || 0,
      ping_quantity: numberUtil.keepEightDecimals(pingPositionAmt) || 0,
      commission: numberUtil.keepEightDecimals(usdt * 0.001) || 0,
      commission_one_way: numberUtil.keepEightDecimals(usdt * 0.0005) || 0,
      commission_margin: Math.abs(numberUtil.keepFourDecimals(usdt / this.btbItem.leverage)) || 0,
      income_res_quantity: this.btbItem.now_position_amt || 0,
      income_rate: numberUtil.countRate(tradeIncome, usdt),
      track_list: [],
      strategy: '2',
      strategy_result: 's-12',
      last_strategy: lastRecord.strategy || '',
      last_strategy_result: lastRecord.strategy_result || '',
      // lastType: String,
      // lastReason: String,
      lastId: lastRecord._id,
      keep_days: this.btbItem.keep_days,
      add_times: this.btbModelUpdateParams.add_times,
      price_change_percent: this.btbItem.price_change_percent,
      quote_volume: this.btbItem.quote_volume,
      no_cover_reason: 0,
      // 详情
      detail: {}
    }
    if (lastRecord._id) {
      const updateData = {
        income_result: lastRecord.income_result || 0,
        commission_margin_result: lastRecord.commission_margin_result || 0,
        income_rate_result: lastRecord.income_rate_result || 0
      }
      const income_result = numberUtil.keepTwoDecimals((params.income || 0) - (params.commission || 0))
      updateData.income_result = numberUtil.keepTwoDecimals(updateData.income_result + income_result)
      updateData.commission_margin_result = numberUtil.keepTwoDecimals(updateData.commission_margin_result + params.commission_margin)
      updateData.income_rate_result = numberUtil.countRate(updateData.income_result, updateData.commission_margin_result)
      // 记录总的保证金
      await ExecuteRecord.update({
        _id: lastRecord._id
      }, updateData)
    }
    await ExecuteRecord.newAndSave(params)
  }
}
